package com.sidom.movieIndexer.facade;

import java.io.File;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;

import static org.apache.commons.lang.Validate.notNull;
import static org.apache.commons.lang.Validate.isTrue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.sidom.movieIndexer.domain.Movie;
import com.sidom.movieIndexer.service.clean.CleanUpService;
import com.sidom.movieIndexer.service.file.FileService;
import com.sidom.movieIndexer.service.google.GoogleSearchService;
import com.sidom.movieIndexer.service.imdb.ImdbService;
import com.sidom.movieIndexer.service.ouput.OutputService;
import com.sidom.movieIndexer.util.CollectionUtils;

/**
 * {@inheritDoc}.
 * 
 * @author Siebe
 */
@Service
public class MovieIndexerFacadeImpl implements MovieIndexerFacade {
	/**
	 * Logger for {@link MovieIndexerFacadeImpl}.
	 */
	private Log log = LogFactory.getLog(MovieIndexerFacadeImpl.class);
	/**
	 * Possible extensions. (e.g. avi, mp4, ...)
	 * Property injected by Spring. 
	 * See movieIndexer.properties.
	 */
	@Value("${extensions}")
	private String extensions;
	/**
	 * FileService injected by Spring.
	 */
	@Autowired
	private FileService fileService;
	/**
	 * GoogleSearchService injected by Spring.
	 */
	@Autowired
	private GoogleSearchService googleSearchService;
	/**
	 * ImdbService injected by Spring.
	 */
	@Autowired
	private ImdbService imdbService;
	/**
	 * CleanUpService injected by Spring.
	 */
	@Autowired
	private CleanUpService cleanUpService;
	/**
	 * CleanUpService injected by Spring.
	 */
	@Autowired
	private OutputService outputService;
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Movie> indexMovies(final String path) {
		return indexMovies(path, StringUtils.commaDelimitedListToSet(extensions));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Movie> indexMovies(final String path, final Set<String> extensions){
		return indexMovies(path, extensions, null);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Movie> indexMovies(final String path, final Set<String> extensions, final Set<String> wordsToRemove){
		log.info("Start indexing movies with path: " + path + ", extensions: " + extensions + " and words to remove: " + wordsToRemove);
		notNull(path, "Path should not be null");
		isTrue(new File(path).exists(), "path should exist");
		notNull(extensions, "Extensions can not be null");
		
		List<Movie> movies = fileService.getVideoFiles(path, extensions);
		
		if(org.apache.commons.collections.CollectionUtils.isEmpty(wordsToRemove)){
			movies = cleanUpService.cleanUpMovies(movies);
		}else{
			movies = cleanUpService.cleanUpMovies(movies, wordsToRemove);
		}
		movies = CollectionUtils.removeDuplicateMovieFiles(movies);
		log.trace("Movies without duplicate Movie Files: " + movies.toString());
		
		movies = googleSearchService.addImdbLinks(movies);
		movies = CollectionUtils.removeDuplicateGoogleSearchResults(movies);
		log.trace("Movies without duplicate Google Search Results: " + movies.toString());
		
		movies = imdbService.addImdbInformation(movies);
		
		String moviesHtml = outputService.createOutPut(movies);
		
		System.out.println(moviesHtml);
		return movies;
	}
	
	/**
	 * Check the attributes for null after the properties have been set.
	 */
	@PostConstruct
	public void afterPropertiesSet() {
		notNull(fileService);
		notNull(googleSearchService);
		notNull(extensions);
		log.debug("Extensions used: " + extensions);
	}
}
